using System.Reflection;
using fCloud.SensorApi;
using fCloud.SensorApi.Models;
using fCloud.SensorApi.Services;
using InfluxDB.Client;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using Pomelo.EntityFrameworkCore.MySql.Internal;
using Serilog;
using Serilog.Events;
using StackExchange.Redis;

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<SensorDbContext>(
    options => options
        .UseMySql(
            connectionString,
            ServerVersion.AutoDetect(connectionString),
            mySqlOptions =>
            {
                mySqlOptions.CommandTimeout(180);
            }),
    ServiceLifetime.Scoped // 显式声明生命周期
);

// 注册MysqlDbService
builder.Services.AddScoped<IMysqlDbService, MysqlDbService>();

// 添加CORS策略（在AddControllers之后添加）
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader();
    });
});
builder.Services.AddControllers();
builder.Services.AddScoped<IReceiverService, ReceiverService>();
builder.Services.AddScoped<IHttpService, HttpService>();
builder.Services.AddScoped<IRedisService, RedisService>();
builder.Services.AddScoped<IInfluxDbService, InfluxDbService>();
builder.Services.AddScoped<ITaskSchedulerService, TaskSchedulerService>();
builder.Services.AddSingleton<ISseService, SseService>();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(
    options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo
        {
            Title = "fCloud.SensorApi", 
            Version = "v1",
            Description = "峰云慧云平台后端接口，为峰云慧前端提供数据支持"
        });
        // 自动包含 XML 注释
        var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        options.IncludeXmlComments(xmlPath);
    }
);
//注册Redis分布式缓存
// builder.Services.AddSingleton<IConnectionMultiplexer>(_ =>
// {
//     var configuration = builder.Configuration.GetSection("Redis");
//     var dbNumber = int.Parse(configuration["DefaultDatabase"]?? "0");
//     var pwd = configuration["Password"];
//     var ssl = bool.Parse(configuration["Ssl"] ?? "false");
//     var conString = configuration["ConnectionString"];
//     if (conString == null) return null!;
//     var options = ConfigurationOptions.Parse(conString);
//     options.AbortOnConnectFail = false;
//     options.DefaultDatabase = dbNumber;
//     options.KeepAlive = 60;
//     options.AbortOnConnectFail = false;
//     options.ConnectTimeout = 5000;
//     if(!string.IsNullOrEmpty(pwd))options.Password = pwd;
//     if(ssl)options.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
//     return ConnectionMultiplexer.Connect(options);
// });
// Program.cs 中优化 Redis 连接配置
builder.Services.AddSingleton<IConnectionMultiplexer>(_ =>
{
    var configuration = builder.Configuration.GetSection("Redis");
    var conString = configuration["ConnectionString"];
    if (conString == null) return null!;
    var pwd = configuration["Password"];
    return ConnectionMultiplexer.Connect(new ConfigurationOptions
    {
        EndPoints = { conString }, // 明确指定单端口
        Password = pwd, // 密码必须与 redis.conf 中 requirepass 一致
        AbortOnConnectFail = false, // 禁用快速失败
        ConnectTimeout = 15000, // 延长至15秒
        SyncTimeout = 15000, // 同步操作超时
        KeepAlive = 180, // 保持连接活跃
        ReconnectRetryPolicy = new LinearRetry(2000), // 线性重试策略
        AsyncTimeout = 10000 // 异步操作超时
    });
});


//配置InfluxDb客户端
builder.Services.AddSingleton<InfluxDBClient>(_ =>
    {
        var config = builder.Configuration.GetSection("InfluxDb");
        var token = config["Token"];
        var url = config["Url"];
        // var username= config["Username"];
        // var password = config["Password"];
        var bucket = config["Bucket"];
        var org = config["Org"];
        var options= new InfluxDBClientOptions(url)
        {
            Token = token,
            Bucket = bucket,
            Org = org,
        };
        var influxdbClient = new InfluxDBClient(options);
        return influxdbClient;
    }
);
builder.Services.AddSingleton<IHostedService, CustomInitializer>();
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
    .WriteTo.Console()
    .WriteTo.File("logs/log.txt",rollingInterval:RollingInterval.Day)
    .CreateLogger();
// Log.Logger = new LoggerConfiguration()
//     .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", LogEventLevel.Warning)
//     .WriteTo.Console()
//     .CreateLogger();

builder.Host.UseSerilog();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(c => {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None); // 默认折叠文档
    });
}
app.UseCors("AllowAll");
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
// app.MapGet("/api/sse/sensor-data", async (HttpContext context,ISseService sseService) =>
// {
//     context.Response.Headers.Append("Content-Type", "text/event-stream");
//     await sseService.AddClient(context);
// });

app.Run(); 